package com.oauth.global.server.service;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.oauth.common.server.util.OAuthRequestUtil;
import com.oauth.components.client.beans.OAuthUrl;
import com.oauth.global.client.beans.ApplicationClientBean;
import com.oauth.global.client.beans.BirthdayClientBean;
import com.oauth.global.server.utils.ApplicationUtil;
import com.oauth.global.server.utils.GlobalUtil;
import com.oauth.service.application.ApplicationService;
import com.oauth.service.application.registry.beans.ApplicationInfoBean;
import com.oauth.service.generic.beans.OAuthServiceBean;
import com.oauth.service.generic.exception.OAuthServiceException;
import com.oauth.service.global.GlobalService;
import com.oauth.service.global.beans.Birthday;
import com.oauth.service.global.beans.GlobalDataType;
import com.oauth.service.global.beans.OAuthAccessToken;
import com.oauth.service.global.beans.OAuthRequestToken;
import com.rapwaves.feeds.Feeds;

@Service
public class GlobalOAuthServiceImpl implements GlobalOAuthService {

	@Autowired
	private GlobalService mGlobalService;

	@Autowired
	private ApplicationService applicationService;

	/**
	 * @param memberId
	 * @return
	 * @throws OAuthServiceException
	 * @see com.oauth.service.application.ApplicationService#getSubscribedApplication(java.lang.Long)
	 */
	@Override
	public List<ApplicationInfoBean> getSubscribedApplication(Long memberId)
			throws OAuthServiceException {
		return applicationService.getSubscribedApplication(memberId);
	}

	/**
	 * @param memberId
	 * @return
	 * @throws OAuthServiceException
	 * @see com.oauth.service.application.ApplicationService#getUnsubscribedApplication(java.lang.Long)
	 */
	@Override
	public List<ApplicationInfoBean> getUnsubscribedApplication(Long memberId)
			throws OAuthServiceException {
		return applicationService.getUnsubscribedApplication(memberId);
	}

	/**
	 * @param memberId
	 * @param applicationId
	 * @throws OAuthServiceException
	 * @see com.oauth.service.application.ApplicationService#unSubscribeApplication(java.lang.Long,
	 *      java.lang.Long)
	 */
	@Override
	public void unSubscribeApplication(Long memberId, Long applicationId)
			throws OAuthServiceException {
		applicationService.unSubscribeApplication(memberId, applicationId);
	}

	@Override
	public OAuthUrl getSignInUrl(Long applicationId) {
		OAuthRequestToken requestToken = mGlobalService.getOAuthRequestToken(applicationId);
		OAuthRequestUtil.createTokenCookies(applicationId, requestToken);
		return new OAuthUrl(requestToken.getAuthorizationUrl());

	}

	@Override
	public void subscribe(Long memberId, Long applicationId) {
		try {
			OAuthRequestToken requestToken = OAuthRequestUtil
					.getOAuthTokenFromCookie(applicationId);
			OAuthAccessToken accessToken = mGlobalService.getOAuthAccessToken(applicationId,
					requestToken);
			persistAccessToken(accessToken, memberId, applicationId);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			OAuthRequestUtil.deleteTokenCookies(applicationId);
		}
	}

	public void persistAccessToken(OAuthAccessToken accessToken, Long memberId, Long applicationId)
			throws Exception {
		OAuthServiceBean serviceBean = new OAuthServiceBean();
		serviceBean.setAccessToken(accessToken.getToken());
		serviceBean.setAccessTokenSecret(accessToken.getTokenSecret());
		serviceBean.setMemberId(memberId);
		serviceBean.setApplicationId(applicationId);
		applicationService.subscribeApplication(serviceBean);
	}

	@Override
	public List<Long> updateStatus(Long pMemberId, String pStatusText, Set<Long> pApplicationIdSet) {
		return mGlobalService.updateStatus(pMemberId, pApplicationIdSet, pStatusText);
	}

	@Override
	public List<BirthdayClientBean> getUpcomingBirthdays(Long pMemberId)
			throws OAuthServiceException {
		Set<Long> applicationIdSet = getApplicationIdSet(pMemberId,
				GlobalDataType.BIRTHDAY_NOTIFACTION);
		List<Birthday> birthdayList = mGlobalService.getUpcomingBirthdays(pMemberId,
				applicationIdSet);
		return GlobalUtil.convertToBirthdayList(birthdayList);
	}

	@Override
	public List<BirthdayClientBean> getUpcomingBirthdays(Long pMemberId, long pAppId) {
		Set<Long> applicationIdSet = new HashSet<Long>(1);
		applicationIdSet.add(pAppId);
		List<Birthday> birthdayList = mGlobalService.getUpcomingBirthdays(pMemberId,
				applicationIdSet);
		return GlobalUtil.convertToBirthdayList(birthdayList);
	}

	@Override
	public List<ApplicationClientBean> getApplicationImages(Long pMemberId,
			GlobalDataType pGlobalDataType) throws OAuthServiceException {
		Set<Long> applicationIdSet = getApplicationIdSet(pMemberId, pGlobalDataType);
		Collection<ApplicationInfoBean> applicationInfo = applicationService
				.getApplicationInfo(applicationIdSet);
		return ApplicationUtil.convertToClientBeans(applicationInfo);
	}

	private Set<Long> getApplicationIdSet(Long pMemberId, GlobalDataType pGlobalDataType)
			throws OAuthServiceException {
		return applicationService.getApplicationIdSetWithDataTypeForMember(pMemberId,
				pGlobalDataType);
	}

	@Override
	public Feeds getFeeds(Long memberId, Long pAppId) throws Exception {
		return mGlobalService.getFeeds(memberId,pAppId);
	}

}
